/*
 * @Author: Wangjun
 * @Date: 2022-09-26 09:17:30
 * @LastEditTime: 2023-05-17 15:30:34
 * @LastEditors: Wangjun
 * @Description:
 * @FilePath: \libs\fastmap\fastmap.go
 * hnxr
 */
package fastmap

// key的类型
type Key interface {
	int64 | int32 | uint64 | uint32 | int | uint
}

//数组最大下标100 w 条shuju
//const MaxSize = 500000

// Map 快速查找，依赖于数组， 下标在最大数组范围内时，使用数组索引，否则直接使用map
type FastMap[K Key, G any] struct {
	fastMap map[K]*G
	array   []*G
	maxSize K
}

func NewFastMap[K Key, G any](size K) *FastMap[K, G] {
	m := new(FastMap[K, G])
	m.Reset()
	m.maxSize = size
	return m
}

func (m *FastMap[K, G]) SetSize(size K) {
	if size < m.maxSize {
		if size < K(len(m.array)) {
			return
		}
		array := make([]*G, size)
		copy(array, m.array)
		m.array = array
	}
}

func (m *FastMap[K, G]) Reset() {
	if m.array != nil && len(m.array) > 0 {
		m.array = m.array[:0]
	}
	m.array = nil
	m.fastMap = make(map[K]*G)
}

func (m *FastMap[K, G]) Set(k K, v *G) {
	if m.fastMap == nil {
		m.fastMap = make(map[K]*G)
	}
	if k < K(len(m.array)) {
		m.array[k] = v
	} else if k < m.maxSize {
		array := make([]*G, k+1)
		copy(array, m.array)
		m.array = array
		m.array[k] = v
	} else {
		m.fastMap[k] = v
	}
}

func (m *FastMap[K, G]) Index(idx K) *G {
	if idx < m.maxSize {
		if idx < K(len(m.array)) {
			return m.array[idx]
		}
		return nil
	}
	return m.fastMap[idx]
}
